home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Utilities / Winter Shell 1.0d2 / Source / Libraries / FolderLib / FolderLib.c next >
Encoding:
C/C++ Source or Header  |  1994-01-17  |  3.7 KB  |  143 lines  |  [TEXT/KAHL]

  1. /* Folder routines.
  2.  
  3.     93/10/13 aih created */
  4.  
  5. #include <string.h>
  6. #include "pstr.h"
  7. #include "FolderLib.h"
  8.  
  9. /* true if the folder exists */
  10. Boolean FolderExists(FileType *folder)
  11. {
  12.     CInfoPBRec pb;
  13.     volatile Boolean exists = true;
  14.     
  15.     TRY {
  16.         if (exists) {
  17.             FileCatalog(folder, &pb);
  18.             exists = ((pb.dirInfo.ioFlAttrib & (1 << kFolderBit)) != 0);
  19.         }
  20.     } CATCH {
  21.         if (FailReason() == fnfErr) {
  22.             exists = false;
  23.             RETRY;
  24.         }
  25.     } ENDTRY;
  26.     return(exists);
  27. }
  28.  
  29. /* count files */
  30. static Boolean valence(const CInfoPBRec *pb, void *data)
  31. {
  32.     (*(long *) data)++;
  33.     return(false);
  34. }
  35.  
  36. /* return number of items in folder */
  37. long FolderValence(FileType *folder, Boolean recursive)
  38. {
  39.     CInfoPBRec pb;
  40.     long count = 0;
  41.  
  42.     require(FolderExists(folder));
  43.     if (! recursive) {
  44.         FileCatalog(folder, &pb);
  45.         count = pb.dirInfo.ioDrNmFls;
  46.     }
  47.     else
  48.         FolderScan(folder, true, valence, &count);
  49.     return(count);
  50. }
  51.  
  52. /* data used while scanning folders, made external to routine to keep
  53.     stack memory usage low during recursive calls */
  54. struct fsdata {
  55.     Boolean (*action)(const CInfoPBRec *pb, void *data);
  56.     void *data;                /* data for action function */
  57.     CInfoPBRec pb;            /* parameter block returned by PBGetCatInfo */
  58.     Boolean recursive;    /* if true, descends subdirectories */
  59.     Boolean stop;            /* if true, operation is stopped */
  60.     FilePNameType name;    /* name of file returned by PBGetCatInfo */
  61. };
  62.  
  63. static void DoScan(struct fsdata *fsdata, FileDirType dir)
  64. {
  65.     short    index;
  66.     long mod;
  67.     OSErr err;
  68.     
  69.     for (index = 1; ! fsdata->stop; index++) {
  70.         
  71.         /* check if directory's file structure has changed, since index
  72.             will no longer be valid if files have been added or removed
  73.             by other processes */
  74.         fsdata->pb.dirInfo.ioFDirIndex = -1;
  75.         fsdata->pb.dirInfo.ioDrDirID = dir;
  76.         FailOSErr(PBGetCatInfo(&fsdata->pb, false));
  77.         check((fsdata->pb.dirInfo.ioFlAttrib & (1 << kFolderBit)) != 0);
  78.         if (index == 1) /* first time, remember mod date */
  79.             mod = fsdata->pb.dirInfo.ioDrMdDat;
  80.         else if (mod != fsdata->pb.dirInfo.ioDrMdDat) /* verify thereafter */
  81.             FailOSErr(paramErr); /* not the best error number... */
  82.         
  83.         /* get data for indexed item */
  84.         fsdata->pb.dirInfo.ioFDirIndex = index;
  85.         fsdata->pb.dirInfo.ioDrDirID = dir;
  86.         fsdata->pb.dirInfo.filler2 = 0; /* ioACUser */
  87.         err = PBGetCatInfo(&fsdata->pb, false);
  88.         if (err == fnfErr) break;
  89.         FailOSErr(err);
  90.         
  91.         /* process file or subdirectory */
  92.         fsdata->stop = fsdata->action(&fsdata->pb, fsdata->data);
  93.         if (! fsdata->stop && fsdata->recursive &&
  94.             (fsdata->pb.dirInfo.ioFlAttrib & (1 << kFolderBit)) != 0)
  95.         {
  96.             DoScan(fsdata, fsdata->pb.dirInfo.ioDrDirID);
  97.         }
  98.     }
  99. }
  100.  
  101. /* Execute the function specified by 'action' for each file and folder
  102.     in the folder specified by 'folder'. If 'resursive' is true then
  103.     subfolders are descended recursively. The 'data' parameter is
  104.     passed to the 'action' function and may contain any user defined
  105.     data. The action function should return true to halt processing. */
  106. void FolderScan(FileType *fp, Boolean recursive, 
  107.     Boolean (*action)(const CInfoPBRec *pb, void *data), void *data)
  108. {
  109.     struct fsdata fsdata;
  110.     FileType folder;
  111.     
  112.     require(FolderExists(fp));
  113.     require(action != NULL);
  114.     FileClone(fp, &folder);
  115.     FileDirID(&folder);
  116.     memclr(&fsdata, sizeof(struct fsdata));
  117.     fsdata.action = action;
  118.     fsdata.data = data;
  119.     fsdata.recursive = recursive;
  120.     pstrcpy(fsdata.name, folder.pnm);
  121.     fsdata.pb.dirInfo.ioNamePtr = fsdata.name;
  122.     fsdata.pb.dirInfo.ioVRefNum = folder.vol;
  123.     fsdata.pb.dirInfo.ioDrDirID = folder.dir;
  124.     DoScan(&fsdata, folder.dir);    
  125. }
  126.  
  127. /* create the folder */
  128. void FolderCreate(FileType *folder)
  129. {
  130.     FileDirType dir;
  131.     
  132.     require(FileValid(folder));
  133.     FailOSErr(DirCreate(folder->vol, folder->dir, folder->pnm, &dir));
  134.     ensure(FolderExists(folder));
  135. }
  136.  
  137. /* delete the folder */
  138. void FolderDelete(FileType *folder)
  139. {
  140.     FileDelete(folder);
  141. }
  142.  
  143.